package net.sharpf2.api.interfaces;

import java.awt.Point;
import net.sharpf2.api.Methods;
import net.sharpf2.sfcore.client.Interface;
import net.sharpf2.api.Globals;
import net.sharpf2.api.util.Mathematics;

/**
 *
 * @author Rick van Biljouw
 */
public class Minimap {
    private static Interface minimap;
    
    /**
     * Gets the minimap interface.
     * @return Interface.
     */
    public static Interface getInterface() {
        if(minimap == null) {
            for(Interface component : Game.getComponents()) {
                if(component != null && component.getContentType() == 1338) {
                    minimap = component;
                }
            }
        }
        return minimap;
    }

    /**
     * Turns a world coordinate into a screen coordinate
     * @param   x   X Coordinate.
     * @param   y   Y Coordinate.
     * @return  Point
     */
    public static Point getCoordinate(int x, int y) {
        x -= Globals.CLIENT.getBaseX();
        y -= Globals.CLIENT.getBaseY();
        final int calculatedX = (int) (x * 4 + 2)
                - Methods.getMyPlayer().getContent().getLocalX() / 128;
        final int calculatedY = (int) (y * 4 + 2)
                - Methods.getMyPlayer().getContent().getLocalY() / 128;

        final Interface mm = getInterface();
        int absX = mm.getAbsoluteX();
        int absY = mm.getAbsoluteY();
        if (mm == null) {
            return new Point(-1, -1);
        }

        final int actDistSq = calculatedX * calculatedX + calculatedY
                * calculatedY;

        final int mmDist = 10 + Math.max(mm.getWidth() / 2,
                mm.getHeight() / 2);
        if (mmDist * mmDist >= actDistSq) {
            int angle = 0x3fff & (int) Globals.CLIENT.getMinimapOffset();
            if (Globals.CLIENT.getMinimapSetting() != 4) {
                angle = 0x3fff & Globals.CLIENT.getMinimapAngle()
                        + (int) Globals.CLIENT.getMinimapOffset();
            }

            int cs = Mathematics.SIN_TABLE[angle];
            int cc = Mathematics.COS_TABLE[angle];
            if (Globals.CLIENT.getMinimapSetting() != 4) {
                final int fact = 256 + Globals.CLIENT.getMinimapScale();
                cs = 256 * cs / fact;
                cc = 256 * cc / fact;
            }

            final int calcCenterX = cc * calculatedX + cs * calculatedY >> 15;
            final int calcCenterY = cc * calculatedY - cs * calculatedX >> 15;

            final int screenx = calcCenterX + absX
                    + mm.getWidth() / 2;
            final int screeny = -calcCenterY + absY
                    + mm.getHeight() / 2;

            return new Point(screenx, screeny);
        }

        return new Point(-1, -1);
    }
    
    /**
     * Clicks a tile quickly.
     * @param x X Coordinate.
     * @param y Y Coordinate.
     */
    public static void clickTileFast(int x, int y) {
        Point m = Minimap.getCoordinate(x, y);
        if (m.x != -1) {
            Globals.CONTROLLER.getMouse().move(m.x, m.y);
            Globals.CONTROLLER.getMouse().click(true);
            Methods.sleep(700);
            while(!Methods.getMyPlayer().getContent().idle() && Methods.getMyPlayer().getContent().getWorldPosition().distance(x, y) > 5 && !Thread.currentThread().isInterrupted()) {
                Methods.sleep(300);
            }
        }        
    }
    
    /**
     * Clicks a tile.
     * @param x X Coordinate
     * @param y Y Coordinate.
     */
    public static void clickTile(int x, int y) {
        Point m = Minimap.getCoordinate(x, y);
        if (m.x != -1) {
            Globals.CONTROLLER.getMouse().move(m.x, m.y);
            Globals.CONTROLLER.getMouse().click(true);
            Methods.sleep(700);
            while(!Methods.getMyPlayer().getContent().idle() && !Thread.currentThread().isInterrupted()) {
                Methods.sleep(300);
            }
        }
    }
   
    /**
     * Walks the specified path.
     * @param path Path to walk.
     */
    public static void walkPath(Point[] path) {
        if(path.length == 0) throw new RuntimeException("Could not find a path, please create one by yourself and call Minimap.walkPath(Point[] path);");
        for (int i = 0; i < path.length; i++) {
            Point p = path[i];
            if (Methods.getMyPlayer().getContent().getWorldPosition().distance(p) > 8) {
                if (p.distance(path[path.length - 1]) < Methods.getMyPlayer().getContent().getWorldPosition().distance(path[path.length - 1])) {
                    clickTileFast(p.x, p.y);
                }
            }
        }
        clickTile(path[path.length - 1].x, path[path.length - 1].y);
    }
    
    private static void handleBlockades() {
        //Content<WorldObject> object = Objects.getAll(4);
    }
   
}
